package net.yegong.mva.pca;

import net.yegong.matrix.DiagonalMatrix;
import net.yegong.matrix.EigenvalueDecomposition;
import net.yegong.matrix.Matrix;
import net.yegong.matrix.SymmetricMatrix;
import net.yegong.mva.ComputingException;

/**
 * The EVD alorithm is much more efficient than ccipca, it invoke the RRR
 * algorithm in lapack to make a EVD (eigen decomposition). That is the fastest
 * EVD of all. Some reports indicated that the SVD is little faster than EVD if
 * you want to get the all principle components.
 * 
 * @author cooper
 */
public class NormalEVDPCACalc extends AbstractPCACalc {
	@Override
	public void calc(Matrix mat, int factor) throws ComputingException {
		calcMean(mat);

		SymmetricMatrix cov = mat.rightMultiplyMyTranspose();
		float alpha = 1.0f / (mat.getRowsCount() - 1);
		cov.scale(alpha);

		// *******************************************************//
		if (factor <= 0) {
			factor = calcFactor(cov.clone());
		}

		EigenvalueDecomposition evd = new EigenvalueDecomposition(cov);
		evd.setErrorsControl(errors);
		evd.partial(0, factor);
		Matrix v = evd.getV();
		DiagonalMatrix d = evd.getD();

		sortEigen(v, d, factor);
		setNegativeComponent(v, d, factor);
		calcContribution(d);
		eigenvalue = d;
		eigenvector = v;
	}
}
